#include "segment_iterator.h"

segment_iterator::segment_iterator(const point& finish_point)
{
    current_cell = (finish_cell = point(floor(finish_point.x), floor(finish_point.y)));
}

segment_iterator::segment_iterator(const point& first_point, const point& second_point)
{
    begin_point = first_point; end_point = second_point;

    current_cell = point(floor(begin_point.x), floor(begin_point.y));
    finish_cell = point(floor(end_point.x), floor(end_point.y));

    sign = ((end_point.y - begin_point.y) > 0) - ((end_point.y - begin_point.y) < 0);

    ready = false;
}

segment_iterator& segment_iterator::operator++()
{
    if (ready)
    {
        ready = false;
        current_cell.y--;

        return *this;
    }

    point tmp_cell = current_cell;
    tmp_cell.x++;

    if (sign > 0)
    {
        tmp_cell.y++;
    }

    int l_turn = left_turn(begin_point, end_point, tmp_cell);

    switch(sign)
    {
    case 1:
        switch(l_turn)
        {
        case 1:
            current_cell.x++;
            break;

        case 0:
            current_cell.x++;
            current_cell.y++;
            break;

        case -1:
            current_cell.y++;
        }
        break;
    case 0:
        current_cell.x++;
        break;

    case -1:
        switch(l_turn)
        {
        case 1:
            current_cell.y--;
            break;

        case 0:
            ready = true;

            current_cell = tmp_cell;            
            break;

        case -1:
            current_cell.x++;
            break;
        }
    }

    return *this;
}

bool segment_iterator::operator !=(const segment_iterator& p) const
{
    return (!(*this == p));
}

bool segment_iterator::operator ==(const segment_iterator& p) const
{
    if (p.finish_cell == finish_cell)
    {
        if (sign == 0)
        {
            return current_cell.x > finish_cell.x;
        } else
        {
            return (current_cell.x == finish_cell.x) && ((current_cell.y - finish_cell.y) * sign > 0);
        }
    }

    return false;
}